package util

import (
	"errors"
	"time"

	"gin-zc/config"

	"github.com/golang-jwt/jwt/v5"
)

// JWTClaims JWT载荷（仅包含必要信息，避免敏感数据）
type JWTClaims struct {
	UserID   uint   `json:"user_id"`
	Username string `json:"username"`
	jwt.RegisteredClaims
}

// GenerateToken 生成JWT令牌
func GenerateToken(userID uint, username string, cfg *config.Config) (string, error) {
	// 设置过期时间
	expireTime := time.Now().Add(time.Duration(cfg.JWTExpire) * time.Second)

	// 构建载荷
	claims := JWTClaims{
		UserID:   userID,
		Username: username,
		RegisteredClaims: jwt.RegisteredClaims{
			ExpiresAt: jwt.NewNumericDate(expireTime), // 过期时间
			IssuedAt:  jwt.NewNumericDate(time.Now()), // 签发时间
			NotBefore: jwt.NewNumericDate(time.Now()), // 生效时间
			Issuer:    "your-app-name",                // 签发者
		},
	}

	// 生成令牌（使用HS256算法）
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	return token.SignedString([]byte(cfg.JWTSecret))
}

// ParseToken 解析JWT令牌，返回用户ID
func ParseToken(tokenString string, cfg *config.Config) (uint, error) {
	// 解析令牌
	token, err := jwt.ParseWithClaims(tokenString, &JWTClaims{}, func(token *jwt.Token) (interface{}, error) {
		return []byte(cfg.JWTSecret), nil
	})
	if err != nil {
		return 0, err
	}

	// 验证令牌有效性
	if claims, ok := token.Claims.(*JWTClaims); ok && token.Valid {
		return claims.UserID, nil
	}

	return 0, errors.New("invalid token")
}
